<?php
declare(strict_types=1);

namespace Zms\HyperfResponse;

use Exception;
use Hyperf\Context\ApplicationContext;
use Hyperf\Context\Context;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\HttpServer\Contract\ResponseInterface as ResponseContractInterface;
use Hyperf\Server\ServerFactory;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface;
use Swoole\WebSocket\Server;
use Zms\Unit\Json;

class Response
{
    /**
     * 获取响应对象
     */
    private static function getResponse(): ResponseInterface
    {
        return Context::get(ResponseInterface::class);
    }


    /**
     * 响应JSON
     * @return Api
     */
    public static function Api(): Api
    {
        try {
            return ApplicationContext::getContainer()->get(Api::class);
        } catch (NotFoundExceptionInterface|ContainerExceptionInterface) {
            return new Api();
        }
    }


    /**
     * 发送Webstock数据
     * @param int $fd
     * @param string $event
     * @param mixed|null $data
     * @return bool
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public static function Webstock(int $fd, string $event, mixed $data = null): bool
    {
        /**
         * @var Server $server
         */
        try {
            $server = ApplicationContext::getContainer()->get(ServerFactory::class)->getServer()->getServer();
            return (bool)(@$server->push($fd, Json::encode(['event' => $event, 'data' => $data])));
        } catch (Exception) {
            return false;
        }
    }

    /**
     * 响应HTML
     * @param string $html
     * @param int $status
     * @return ResponseInterface
     */
    public static function Html(string $html, int $status = 200): ResponseInterface
    {
        return self::getResponse()->withStatus($status)->withHeader('Content-Type', 'text/html;charset=utf-8')->withBody(new SwooleStream($html));
    }


    /**
     * 中断响应
     * @return ResponseInterface
     */
    public static function Interrupt(): ResponseInterface
    {
        return self::getResponse()->withStatus(404);
    }


    /**
     * 响应文本
     * @param string $html
     * @param int $status
     * @return ResponseInterface
     */
    public static function text(string $html, int $status = 200): ResponseInterface
    {
        return self::getResponse()->withStatus($status)->withHeader('Content-Type', 'text/plain;charset=utf-8')->withBody(new SwooleStream($html));
    }


    /**
     * 页面重定向
     */
    public static function redirect(string $toUrl, int $status = 302, string $schema = 'http'): ?Psr7ResponseInterface
    {
        try {
            return ApplicationContext::getContainer()->get(ResponseContractInterface::class)->redirect($toUrl, $status, $schema);
        } catch (NotFoundExceptionInterface|ContainerExceptionInterface) {
            return null;
        }
    }
}